home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
PXDTUT5.ZIP
/
PXDTUT5.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-08-14
|
13KB
|
547 lines
Program VESA_UNIT;
uses
crt;
CONST
HEXTABLE : Array[0..15] of char
= ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
type
ListOfAvailModesT = Array[0..255] of word; {terminated by -1 ($FFFF) }
ListOfAvailModesP = ^ListOfAvailModesT;
String2 = String[2];
String4 = String[4];
VESAInfoT = record
VESASignature : array[0..3] of byte;
VESAVersion : word;
OEMStringPtr : Pchar;
Capabilities : array[0..3] of byte;
VideoModePtr : ListOfAvailModesP;
TotalMemory : word;
Reserved : Array[0..235] of byte;
end;
ModeAttributesT = (Available, {mode avail on current hardware config..}
Reserved, {VESA 1.2 and above this is set to 1}
BIOSFunctionsSupport,{Scroll, TTY output and pixel output}
color,
graphic,
bit5,
bit6,
bit7,
bit8);
WindowAttributesT = (Supported,R,W); {rest of the bits are unused...}
VESAModeInfoT = record
ModeAttributes : set of ModeAttributesT;
WinAAttributes : set of WindowAttributesT;
WinBAttributes : set of WindowAttributesT;
WinGranularity : word;
WinSize : word;
WinASegment : word;
WinBSegment : word;
BankSwitch : procedure;
BytesPerScanLine : word;
{Xtended Information}
XResolution : word;
YResolution : word;
XCharSize : byte;
YCharSize : byte;
NumberOfPlanes : byte;
BitsPerPixel : byte;
NumberOfBanks : byte;
MemoryModel : byte;
BankSize : byte;
NumberOfImagePages : byte;
Reserved : Array[0..225] of byte;
{reserved is for something we won't think about now...
true color and stuff... }
end;
var
VESAInfo : VESAInfoT;
VESAModeInfo : VESAModeInfoT;
Cur_page : word;
Bankmult : word;
BankShiftModifier : word;
VESAModeList : Array[0..40] of word;
counter : word;
Procedure Error(msg : string);
begin
asm
mov ax,03h
int 10h
end;
Writeln(msg);
HALT;
end;
function Byte2Hex(b : byte) : String2;
var
temp : string2;
begin
temp[1] := HEXTABLE[b shr 4];
temp[2] := HEXTABLE[b mod 16];
Byte2Hex := temp;
end;
function Word2Hex(w : word) : String4;
begin
Word2Hex:=Byte2Hex(hi(w))+Byte2Hex(lo(w));
end;
FUNCTION GetVESAInfo : boolean;
Assembler;
asm
mov ah,4Fh
mov al,00h
lea di,VESAInfo
int 10h
cmp ah,0
jne @fail
mov ax,1
jmp @out
@fail:
mov ax,0
@out:
end;
FUNCTION GetVESAModeInfo(mode : word) : boolean;
Assembler;
asm
mov ah,4Fh
mov al,01h
xor cx,cx
mov cx,mode
lea di,VESAModeInfo
int 10h
cmp ah,0
jne @fail
mov ax,1
jmp @out
@fail:
mov ax,0
@out:
end;
Procedure SetBank(nr : word);
Assembler;
asm
xor bl,bl {Window 0 selected}
mov dx,nr
call [VESAModeInfo.BankSwitch]
mov dx,nr {dx is destroyed by far procedure call}
mov cur_page,dx {update global page variable}
end;
Procedure SetLogicalScanline(width : word);
Assembler;
asm
mov ah,4Fh
mov al,06h
mov bl,0
mov cx,width
int 10h
end;
Procedure SetScreenPosition(x,y : word);
Assembler;
asm
mov ah,4Fh
mov al,07h
xor bx,bx
mov cx,[x]
mov dx,[y]
int 10h
end;
FUNCTION SetVESAMode(mode : word) : boolean;
Assembler;
asm
mov ax,03h
int 10h {start from textmode}
mov ah,4Fh
mov al,02h
mov bx,mode
int 10h
cmp ah,0
jne @fail {set the VESA mode through VESA function 02h}
mov ah,4Fh
mov al,05h
xor bx,bx
mov dx,0
int 10h
mov cur_page,0 {initialize global page variable}
cmp ah,0
jne @fail {Set bank 0}
mov ax,1 {Set call to succesful}
jmp @out
@fail:
mov ax,0
@out:
end;
PROCEDURE VESAputpixel(x, y : WORD; c : BYTE);
VAR
bank : WORD;
offs : longint;
BEGIN
offs := LONGINT(y) * VESAModeInfo.Xresolution + x;
bank := offs SHR (16-BankShiftModifier);
offs := offs - (bank SHL (16-BankShiftModifier));
IF bank <> Cur_page THEN {page = global var - active page}
BEGIN
cur_page := bank;
ASM
Xor bl,bl
mov dx,bank
call [VESAModeInfo.BankSwitch]
END;
END;
ASM
MOV AX, $A000
MOV ES, ax
MOV DI, WORD(offs)
MOV AL, c
MOV ES:[DI], AL
END;
END;
PROCEDURE ClearScreen(color : byte);
var
Xres, Yres : longint;
number_of_segments : longint;
i : integer;
begin
Xres := VESAModeInfo.Xresolution;
Yres := VESAModeInfo.Yresolution;
number_of_segments := Round(((Xres * Yres)/65536)+0.5)-1;
for i := 0 to number_of_segments do
begin
SetBank(i*BankMult);
asm
mov cx, 32768;
mov ax,$A000
mov es,ax
xor di,di
mov al,[color]
mov ah,al
rep stosw
end;
end;
end;
Procedure SetCursor(X,Y : byte);
Assembler;
asm
mov ah,02h
xor bh,bh
mov dh,[Y]
mov dl,[X]
int 10h
end;
Procedure WriteChar(chnr,color : byte);
assembler;
asm
mov ah,09h
mov al,[chnr]
mov bh,0
mov bl,[color]
mov cx,1
int 10h
end;
Procedure WriteXY(x,y : integer;str : string; color : byte);
var
i : byte;
begin
SetCursor(x,y);
for i := 1 to length(str) do
begin
WriteChar(ord(str[i]),color);
SetCursor(X+i,Y);
end;
end;
function ModeInList(nr : word) : boolean;
var
i : integer;
found : boolean;
begin
found := false;
for i := 0 to 40 do
if VESAModeList[i] = nr then found := true;
if found then ModeInList := true else ModeInList := false;
end;
Procedure Calc_variables;
begin
Case VESAModeInfo.WinGranularity of
1 : BankShiftModifier := 6;
2 : BankShiftModifier := 5;
4 : BankShiftModifier := 4;
8 : BankShiftModifier := 3;
16 : BankShiftModifier := 2;
32 : BankShiftModifier := 1;
64 : BankShiftModifier := 0;
end; {With granularities smaller than 64 but with page-size 64K the
banknr for each full segment of SVGA graphic will not be 0,1,2,3
but multiplied with BankMult ( 2^BankShiftModifier for easy bit
shifting) }
BankMult := 64 div VESAModeInfo.WinGranularity;
end;
Procedure WriteVESAInfo;
var
i : integer;
begin
for i := 0 to 3 do
Write(chr(VESAInfo.VESASignature[i]));
Write(' ');
Writeln('Version : ',VESAInfo.VESAVersion shr 8,'.',VESAInfo.VESAVersion mod 256);
Writeln(VESAInfo.OEMStringPtr);
Writeln('Total Memory : ',VESAInfo.TotalMemory,' X 64Kb = '
,VESAInfo.TotalMemory * 65536,' bytes = ',
VESAInfo.TotalMemory * 65536 div 1048576 ,'MB');
Writeln;
end;
Procedure ModeList;
var
i : integer;
p : ^word;
begin
Writeln('Modes Available : ');
Writeln;
for i := 0 to 40 do VESAModeList[i] := 0;
i := 0;
p := pointer(VESAInfo.VideoModePtr);
while p^ <> $FFFF do
begin
if Not(ModeInList(P^)) then
begin
VESAModeList[i] := p^;
inc(i);
Write('$',Word2Hex(p^));
GetVESAModeInfo(p^);
write(' ',VESAModeInfo.Xresolution : 5,' X ',VESAModeInfo.Yresolution:3);
Write(' BPP : ',VESAModeInfo.BitsPerPixel:2);
if color in VESAModeInfo.ModeAttributes then Write(' Color') else
write(' Monocrome');
if graphic in VESAModeInfo.ModeAttributes then Write(' Graphic') else
write(' Textmode');
if supported in VESAModeInfo.WinAAttributes then
begin
write(' Win A :');
if R in VESAModeInfo.WinAAttributes then Write(' R');
if W in VESAModeInfo.WinAAttributes then Write('W');
write(' at : $',Word2Hex(VESAModeInfo.WinASegment));
end;
if supported in VESAModeInfo.WinBAttributes then
begin
write(' Win B :');
if R in VESAModeInfo.WinBAttributes then Write(' R');
if W in VESAModeInfo.WinBAttributes then Write('W');
write(' at : $',Word2Hex(VESAModeInfo.WinASegment));
end;
Write(' Gran : ',VESAModeInfo.WinGranularity:2,'Kb');
Writeln;
end;
inc(p);
end;
end;
BEGIN
asm
mov ax,03h
int 10h
end;
Clrscr;
Writeln(' ****************************************************************');
Writeln(' * *');
Writeln(' * SVGA using VESA 1.2 *');
Writeln(' * by : Telemachos *');
Writeln(' * *');
Writeln(' ****************************************************************');
Writeln;
Writeln(' Hiya! ');
Writeln(' Welcome to the Peroxide Programming Tips #5');
Writeln(' This one is on coding the SVGA card using VESA 1.2');
Writeln(' This code *SHOULD* work on every graphic card that');
Writeln(' supports VESA 1.2 (which is about every card now a days)');
Writeln(' ');
Writeln(' This program will :');
Writeln(' 1) Display information about your SVGA card');
Writeln(' 2) Display available modes on your card..');
Writeln(' 3) Cycle through the most common SVGA modes (256 colors)');
Writeln(' 4) Show you how to hardware scroll using the VESA BIOS');
Writeln;
Writeln(' Hit any key to get started....');
Writeln;
readkey;
clrscr;
If Not(GetVesaInfo) then Error('No VESA installed...');
WriteVESAInfo;
ModeList;
Writeln;
Writeln('Press space to continue');
readkey;
Randomize;
if ModeInList($100) then
begin
if NOT(SetVESAMode($100)) then exit;
GetVESAModeInfo($100);
Calc_variables;
ClearScreen(Random(255));
for counter := 0 to 10000 do
VESAPutPixel(Random(VESAModeInfo.Xresolution),
Random(VESAModeInfo.Yresolution),
Random(255));
WriteXY(5,2,'This is 640 X 400 X 256',50);
WriteXY(5,4,'Press space for next mode...',50);
fillchar(VESAModeInfo,256,0);
end;
readkey;
if ModeInList($101) then
begin
if NOT(SetVESAMode($101)) then exit;
GetVESAModeInfo($101);
Calc_variables;
ClearScreen(Random(255));
for counter := 0 to 10000 do
VESAPutPixel(Random(VESAModeInfo.Xresolution),
Random(VESAModeInfo.Yresolution),
Random(255));
WriteXY(5,2,'This is 640 X 480 X 256',50);
WriteXY(5,4,'Press space for next mode...',50);
fillchar(VESAModeInfo,256,0);
end;
readkey;
if ModeInList($103) then
begin
if NOT(SetVESAMode($103)) then exit;
GetVESAModeInfo($103);
Calc_variables;
ClearScreen(Random(255));
for counter := 0 to 10000 do
VESAPutPixel(Random(VESAModeInfo.Xresolution),
Random(VESAModeInfo.Yresolution),
Random(255));
WriteXY(5,2,'This is 800 X 600 X 256',50);
WriteXY(5,4,'Press space for next mode...',50);
fillchar(VESAModeInfo,256,0);
end;
readkey;
if ModeInList($105) then
begin
if NOT(SetVESAMode($105)) then exit;
if Not(GetVESAModeInfo($105)) then Error('Ups.. noget galt her...');
Calc_variables;
ClearScreen(Random(255));
for counter := 0 to 10000 do
VESAPutPixel(Random(VESAModeInfo.Xresolution),
Random(VESAModeInfo.Yresolution),
Random(255));
WriteXY(5,2,'This is 1024 X 768 X 256',50);
WriteXY(5,4,'Press space for Hardware Scroll demo...',50);
fillchar(VESAModeInfo,256,0);
end;
readkey;
if ModeInList($101) then
begin
if NOT(SetVESAMode($101)) then exit;
GetVESAModeInfo($101);
Calc_variables;
SetLogicalScanLine(1024);
VESAModeInfo.Xresolution := 1024;
SetScreenPosition(0,0);
ClearScreen(Random(255));
for counter := 0 to 10000 do
VESAPutPixel(Random(VESAModeInfo.Xresolution),
Random(VESAModeInfo.Yresolution*2),
Random(255));
for counter := 0 to 150 do SetScreenPosition(counter*2,0);
for counter := 150 downto 0 do SetScreenPosition(counter*2,0);
for counter := 0 to 150 do SetScreenPosition(counter*2,Counter*2);
for counter := 150 to 1040 do SetScreenPosition(300,counter*2);
fillchar(VESAModeInfo,256,0);
end
else
WriteXY(5,7,'Mode $101 is unavailble on your card.. Skipping Scroll.',50);
delay(2000);
asm
mov ax,03h
int 10h
end;
Writeln('All for now.. Signin'' out');
Writeln(' Telemachos.');
delay(5000);
END.